import React, { useState } from 'react';
import { Divider, message, Modal, Button, Progress } from 'antd';
import { UploadOutlined, PlusOutlined, CloseOutlined } from '@ant-design/icons';
import style from './style.module.less';
import { useDynamicList, useMount, useUpdateEffect } from 'ahooks';
import ReactScroll from 'react-custom-scrollbars';
import { KQueue } from '@kingeast/queue';
import { apiUploadImage } from '@/api/upload.api';
import { ke } from '@/plugins/ke';

export interface UploadFile {
  key: string;
  file: File;
  preview: string;
  result?: any;
}

export default (props: {
  visible: boolean;
  multiple?: boolean;
  onOk: (data: string[]) => void;
  onCancel: () => void;
  closeClear?: boolean; // 关闭时是否清除已上传图片
}) => {
  const closeClear: boolean = props?.closeClear ?? true;
  let allProgress: any = {}; // 为了顺滑的ui动画
  let allSuccess: any = {}; // 为了顺滑的ui动画
  const files = useDynamicList<UploadFile>([]);
  const [progress, setProgress] = useState<{ [key: string]: number }>({});
  const [success, setSuccess] = useState<{ [key: string]: boolean }>({});
  // 锁定上传按钮
  const [locked, setLocked] = useState<boolean>(false);
  // 已上传的文件列表
  const [results, setResults] = useState<string[]>([]);

  // 文件选择
  const onFileChange = (file: any) => {
    const fs: UploadFile[] = [];

    for (let f of file.target.files) {
      if (files.list.includes(f)) {
        message.error('文件已在列表');
        return;
      }
      const key = ke.randomString(32);
      fs.push({
        key,
        file: f,
        preview: window.URL.createObjectURL(f),
      });
    }

    files.resetList([...files.list, ...fs]);

    file.target.value = '';
  };

  // 删除文件
  const onRemoveFile = (idx: number) => {
    const key = files.list[idx].key;
    delete allProgress[key];
    delete allSuccess[key];
    setProgress({ ...allProgress });
    setProgress({ ...allSuccess });
    files.remove(idx);
  };

  // 开始上传
  const onStartUpload = () => {
    setLocked(true);
    allSuccess = {};
    allProgress = {};
    setProgress({});
    setSuccess({});

    // 过滤掉已上传的文件
    const fs = files.list.filter(f => !success[f.key]);
    const queue = new KQueue(3);

    queue.setTask(fs);

    queue.addHandler((data: UploadFile) => {
      return apiUploadImage(data.file, null, evt => {
        const percent: number = Math.floor((100 * evt.loaded) / evt.total);

        allProgress[data.key] = percent;
        setProgress({ ...allProgress });
        if (percent === 100) {
          allSuccess[data.key] = true;
          setSuccess({ ...allSuccess });
        }
      }).then(result => result.data);
    });

    queue.start().then((retResults: any[]) => {
      setProgress({});
      setLocked(false);
      setResults([
        ...results,
        ...retResults.filter(res => res).map(res => res.src),
      ]);
    });
  };

  // 文件框
  const fileWrap = () => (
    <input
      className={style.file}
      type={'file'}
      accept={'image/*'}
      multiple={props.multiple}
      onChange={onFileChange}
    />
  );

  // 选择图片按钮
  const selectImageBtn = () => (
    <div className={style.wrapper}>
      <div className={style.uploadBtn}>
        <UploadOutlined />
        {fileWrap()}
        选择图片
      </div>
    </div>
  );

  // 上传信息
  const uploadStatus = () => {
    return (
      <div className={style.status}>
        <div className={style.statusBar}>
          <span>已选择{files.list.length}个文件</span>

          <span>
            <Button
              disabled={
                !files.list.length ||
                locked ||
                files.list.length === Object.keys(success).length
              }
              onClick={onStartUpload}
            >
              开始上传
            </Button>
          </span>
        </div>

        <Divider />
      </div>
    );
  };

  return (
    <Modal
      visible={props.visible}
      width={760}
      onOk={() => {
        props.onOk(results);
        if (closeClear) {
          allProgress = {};
          allSuccess = {};
          setSuccess({});
          setProgress({});
          setResults([]);
          files.resetList([]);
        }
      }}
      onCancel={props.onCancel}
      title={'图片上传'}
    >
      <div>
        {/*<div>*/}
        {/*  <Button type={'ghost'}>开始上传</Button>*/}
        {/*</div>*/}

        {uploadStatus()}

        {!!files.list.length && (
          <div className={style.container}>
            <ReactScroll>
              {files.list.map((img, i) => (
                <div key={i} className={style.item}>
                  <div className={style.remove}>
                    <CloseOutlined
                      title={'删除'}
                      onClick={() => onRemoveFile(i)}
                    />
                  </div>

                  {!success[img.key] && progress[img.key] && (
                    <div className={style.progress}>
                      <Progress
                        type={'circle'}
                        percent={progress[img.key] ?? 0}
                        width={50}
                      />
                    </div>
                  )}

                  {/* 成功层 */}
                  {success[img.key] && <div className={style.success} />}

                  <img src={img.preview} />
                </div>
              ))}
              {props.multiple && files.list.length === 1 && (
                <div className={[style.item, style.plusAdd].join(' ')}>
                  {fileWrap()}

                  <PlusOutlined size={36} />
                </div>
              )}
            </ReactScroll>
          </div>
        )}

        {files.list.length === 0 && selectImageBtn()}
      </div>
    </Modal>
  );
};
